﻿using System;
using System.Collections.Generic;
using DevExpress.XtraBars.Ribbon;
using Pharmacy.Data;
using System.Linq;
using Pharmacy.Ultilities;
using Pharmacy.Data.Repositories;
using DevExpress.XtraBars;
using Pharmacy.Ultilities.Configurations;
using DevExpress.LookAndFeel;
using PharmacyPharnet.Core;
using PharmacyPharnet.Core.CustomEventArgs;
using DevExpress.XtraNavBar;
using System.Windows.Forms;
using Pharmacy.Ultilities.Resources;
using System.Drawing;
using PharmacyPharnet.Core.ContextMenu;
using DevExpress.XtraTabbedMdi;
using DevExpress.XtraTab.ViewInfo;
using Pharmacy.ExceptionHandling;


namespace PharmacyPharnet
{
    public partial class FrmMain : RibbonForm
    {
        #region Declarations
        public delegate void LoginHandler();   
        public event LoginHandler LoginEvent;
        private readonly IObjectContext pharmacyContext;
        private MenuRepository lstMenu;
        CustomBasePopUp _popUpclose;        
        #endregion

        #region Constructors
        public FrmMain()
        {
            pharmacyContext = ObjectContextFactory.CreatePharmacyContext(UserName: Global.UserName, connectionString: ConfigManager.DIOConfig.ConnectionString);
            InitializeComponent();
            UserLookAndFeel.Default.SetSkinStyle(ConfigManager.DIOConfig[Constant.SKINSTYLE]);
        }
        #endregion

        #region Properties
        #endregion

        #region Methods
        private void LoadSkin()
        {
            GalleryDropDown skins = new GalleryDropDown() { Ribbon = rbMainMenu };
            DevExpress.XtraBars.Helpers.SkinHelper.InitSkinGalleryDropDown(skins);
            skins.GalleryItemCheckedChanged += new GalleryItemEventHandler(skins_GalleryItemCheckedChanged);
            bbiChooseSkin.DropDownControl = skins;
        }

        void skins_GalleryItemCheckedChanged(object sender, GalleryItemEventArgs e)
        {
            ConfigManager.DIOConfig[Constant.SKINSTYLE] = e.Item.Caption;
        }

        /// <summary>
        /// Close form and clear register event before log out
        /// </summary>
        private bool Logout()
        {
            Form[] frms = this.MdiChildren;
            foreach (Form frm in frms)
            {
                frm.Close();
            }
            ViewManager.WindowChanged -= new EventHandler<WindowEventArgs>(ViewManager_WindowChanged);
            if (this.MdiChildren.Length == 0)
                return true;
            else
                return false;            
        }

        private void DoLogin()
        {
            LoginEvent();
        }

        void LoadPopUpClose()
        {
            _popUpclose = new CustomBasePopUp(barManager1);

            CustomButtonBarItem itemCloseAllButThis = _popUpclose.AddMenuItem("bbiCloseButAllThis", "Đóng tất cả các form còn lại");
            Image img = Image.FromFile(IOHelper.CombinePath(IOHelper.ExecutePath, @"Images\delete2.png"));
            itemCloseAllButThis.Glyph = img.GetThumbnailImage(16, 16, null, IntPtr.Zero);
            itemCloseAllButThis.Execute += new ExecuteHandler(itemCloseAllButThis_Execute);

            CustomButtonBarItem itemCloseAll = _popUpclose.AddMenuItem("bbiCloseAll", "Đóng tất cả các form");            
            itemCloseAll.Glyph = img.GetThumbnailImage(16, 16, null, IntPtr.Zero);
            itemCloseAll.Execute += new ExecuteHandler(itemCloseAll_Execute);
        }

        void CloseAllButThis()
        {
            XtraMdiTabPage selectedPage = xtraTabbedMdiManager1.SelectedPage;
            for (int i = xtraTabbedMdiManager1.Pages.Count - 1; i >= 0; i--)
            {
                XtraMdiTabPage page = xtraTabbedMdiManager1.Pages[i];
                if (page.MdiChild.Name != selectedPage.MdiChild.Name)
                    page.MdiChild.Close();
            }
        }

        void CloseAll()
        {
            for (int i = xtraTabbedMdiManager1.Pages.Count - 1; i >= 0; i--)
            {
                XtraMdiTabPage page = xtraTabbedMdiManager1.Pages[i];
                if (page != null)
                    page.MdiChild.Close();
            }
        }

        #endregion

        #region Load Menu
        private void LoadListMenu()
        {
            lstMenu = new MenuRepository(pharmacyContext);
            CreateMenuPage(lstMenu);
            if (rbMainMenu.Pages.Count > 0)
                rbMainMenu.SelectedPage = rbMainMenu.Pages[0];
        }

        private void CreateMenuPage(MenuRepository lstMenu)
        {
            List<Pharmacy.Data.Entity.Menu> menuPages = lstMenu.AsQueryable().Where<Pharmacy.Data.Entity.Menu>(delegate(Pharmacy.Data.Entity.Menu m)
            {
                return m.MenuType.GetValueOrDefault() == (int)Enums.MenuType.Page && m.IsVisible == true;
            }).ToList();
            if (menuPages != null && menuPages.Count > 0)
            {
                RibbonPage rbMenuPage = null;
                foreach (Pharmacy.Data.Entity.Menu m in menuPages)
                {
                    rbMenuPage = new RibbonPage(m.NameDisplay);
                    rbMenuPage.Name = m.Name;
                    rbMainMenu.Pages.Add(rbMenuPage);

                    // Create Menu Group for current page
                    CreateMenuGroup(lstMenu, rbPage: rbMenuPage, parentMenu: m);
                }
            }
        }

        private void CreateMenuGroup(MenuRepository lstMenu, RibbonPage rbPage, Pharmacy.Data.Entity.Menu parentMenu)
        {
            List<Pharmacy.Data.Entity.Menu> menuGroups = lstMenu.AsQueryable().Where<Pharmacy.Data.Entity.Menu>(delegate(Pharmacy.Data.Entity.Menu m)
            {
                return m.MenuType.GetValueOrDefault() == (int)Enums.MenuType.Group && m.ParentID == parentMenu.ID && m.IsVisible == true;
            }).ToList();
            if (menuGroups != null && menuGroups.Count > 0)
            {
                RibbonPageGroup rbMenuGroup = null;
                foreach (Pharmacy.Data.Entity.Menu m in menuGroups)
                {
                    rbMenuGroup = new RibbonPageGroup(m.NameDisplay);
                    rbMenuGroup.Name = m.Name;
                    rbPage.Groups.Add(rbMenuGroup);

                    // Create Menu item in current menu group
                    CreateBarButtonItem(lstMenu, rbMenuGroup, m);
                }
            }
        }

        private void CreateBarButtonItem(MenuRepository lstMenu, RibbonPageGroup rbgMenuGroup, Pharmacy.Data.Entity.Menu parentMenu)
        {
            List<Pharmacy.Data.Entity.Menu> menuItems = lstMenu.AsQueryable().Where<Pharmacy.Data.Entity.Menu>(delegate(Pharmacy.Data.Entity.Menu m)
            {
                return m.MenuType.GetValueOrDefault() == (int)Enums.MenuType.Item && m.ParentID == parentMenu.ID && m.IsVisible == true;
            }).ToList();

            if (menuItems != null && menuItems.Count > 0)
            {
                BarButtonItem rbMenuItem = null;
                foreach (Pharmacy.Data.Entity.Menu m in menuItems)
                {
                    rbMenuItem = rbMainMenu.Items.CreateButton(m.NameDisplay);
                    rbMenuItem.Id = m.ID;
                    rbMenuItem.Name = m.Name;
                    rbMenuItem.LargeGlyph = m.Icon.GetImageFromFile(false);
                    rbgMenuGroup.ItemLinks.Add(rbMenuItem).BeginGroup = true;
                    // Create Sub Menu Item in current menu item
                    CreateSubMenuItem(lstMenu, rbMenuItem, m);
                }
            }
        }

        private void CreateSubMenuItem(MenuRepository lstMenu, BarButtonItem bbiItem, Pharmacy.Data.Entity.Menu parentMenu)
        {
            List<Pharmacy.Data.Entity.Menu> menuSubItems = lstMenu.AsQueryable().Where<Pharmacy.Data.Entity.Menu>(delegate(Pharmacy.Data.Entity.Menu m)
            {
                return m.MenuType.GetValueOrDefault() == (int)Enums.MenuType.SubItem && m.ParentID == parentMenu.ID && m.IsVisible == true;
            }).ToList();
            if (menuSubItems != null && menuSubItems.Count > 0)
            {
                bbiItem.ActAsDropDown = true;
                bbiItem.ButtonStyle = BarButtonStyle.DropDown;

                BarButtonItem rbSubMenuItem = null;
                PopupMenu barSubItem = new PopupMenu();
                foreach (Pharmacy.Data.Entity.Menu m in menuSubItems)
                {
                    rbSubMenuItem = rbMainMenu.Items.CreateButton(m.NameDisplay);
                    rbSubMenuItem.Id = m.ID;
                    rbSubMenuItem.Name = m.Name;
                    rbSubMenuItem.Glyph = m.Icon.GetImageFromFile(true);
                    rbSubMenuItem.ItemClick += rbSubMenuItem_ItemClick;
                    barSubItem.AddItem(rbSubMenuItem);
                }
                bbiItem.DropDownControl = barSubItem;
            }
            else
            {
                bbiItem.ItemClick += rbSubMenuItem_ItemClick;
            }
        }

        void rbSubMenuItem_ItemClick(object sender, ItemClickEventArgs e)
        {
            Pharmacy.Data.Entity.Menu objMenu = lstMenu.AsQueryable().Where(m => m.ID == e.Item.Id).FirstOrDefault();
            if (objMenu != null)
            {
                //ViewManager.ShowView(new FrmListMasterData());
                ViewManager.ShowView(objMenu.ID);
            }
        }

        private string GetCaption(string txt)
        {
            string caption = string.Empty;
            caption = SR.Instance.GetString(txt);
            if (string.IsNullOrEmpty(caption))
            {
                caption = txt;
            }
            return caption;
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            LoadSkin();
            LoadListMenu();
            LoadPopUpClose();

            ViewManager.InitializeTypeInfo();

            ViewManager.WindowChanged += new EventHandler<WindowEventArgs>(ViewManager_WindowChanged);
        }
        #endregion

        #region Event Handlers
        void ViewManager_WindowChanged(object sender, WindowEventArgs e)
        {
            Control window = e.Window as Control;
            DialogViewBase viewBase = null;
            switch (e.Action)
            {
                case Pharmacy.Ultilities.Enums.WindowAction.Show:
                    NavBarItem newItem = new NavBarItem(GetCaption(e.Window.FeatureTypeName));
                    newItem.Tag = window;
                    newItem.LinkClicked += new NavBarLinkEventHandler(item_LinkClicked);

                    if ((window as DialogViewBase) != null)
                    {
                        viewBase = (window as DialogViewBase);
                    }
                    else
                    {
                        viewBase = (window.Parent as DialogViewBase);
                        window.Dock = DockStyle.Fill;
                    }
                    if (!this.IsMdiContainer) this.IsMdiContainer = true;
                    viewBase.MdiParent = this;
                    //viewBase.FormClosing += new FormClosingEventHandler(MdiChild_FormClosing);                        
                    //viewBase.Show();
                    break;

                //case WindowAction.Close:
                //    for (int i = 0; i < nbgWindow.ItemLinks.Count; i++)
                //    {
                //        NavBarItem item = nbgWindow.ItemLinks[i].Item;
                //        if ((item.Tag as IView).FeatureTypeName == e.Window.FeatureTypeName)
                //        {
                //            item.LinkClicked -= new NavBarLinkEventHandler(item_LinkClicked);
                //            nbgWindow.ItemLinks.Remove(item);
                //            item.Dispose();
                //            break;
                //        }
                //    }
                //    break;
            }
        }

        void item_LinkClicked(object sender, NavBarLinkEventArgs e)
        {
            NavBarItem item = e.Link.Item;
            DialogViewBase view = null;
            if ((item.Tag as DialogViewBase) != null)
            {
                view = item.Tag as DialogViewBase;
            }
            else
            {
                view = (item.Tag as ControlViewBase).Parent as DialogViewBase;
            }
            view.Activate();
        }

        void itemCloseAllButThis_Execute(object sender, CustomBaseEventArg e)
        {
            try
            {
                CloseAllButThis();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        void itemCloseAll_Execute(object sender, CustomBaseEventArg e)
        {
            try
            {
                CloseAll();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Có lỗi xảy ra. Vui lòng liên hệ Người quản trị hệ thống để được hỗ trợ.");
                ExceptionHandler.LogWriter.Write(ex, ExceptionHandler.LOG_CAT_GENERAL);
            }
        }
        #endregion

        private void btnExit_ItemClick(object sender, ItemClickEventArgs e)
        {
            try
            {
                if (Logout())
                    DoLogin();                
            }
            catch (Exception ex)
            {
                MessageBox.Show("Có lỗi xảy ra. Vui lòng liên hệ Người quản trị hệ thống để được hỗ trợ.");
                ExceptionHandler.LogWriter.Write(ex, ExceptionHandler.LOG_CAT_GENERAL);
            }
        }

        private void xtraTabbedMdiManager1_MouseUp(object sender, MouseEventArgs e)
        {
            try
            {
                if (e.Button == MouseButtons.Right)
                {
                    BaseTabHitInfo info = xtraTabbedMdiManager1.CalcHitInfo(e.Location);
                    if (info.HitTest == XtraTabHitTest.PageHeader)
                    {
                        XtraMdiTabPage selectedPage = info.Page as XtraMdiTabPage;
                        if (selectedPage != null)
                        {
                            _popUpclose.ShowPopup(MousePosition);
                        }
                    }
                }
                else
                    _popUpclose.HidePopup();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Có lỗi xảy ra. Vui lòng liên hệ Người quản trị hệ thống để được hỗ trợ.");
                ExceptionHandler.LogWriter.Write(ex, ExceptionHandler.LOG_CAT_GENERAL);
            }
        }
    }
}